package jp.android_group.attender.android.entity;

/*
 * Copyright (c) 2009, "Japan Android Group Attender Team"
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

import java.io.Serializable;
import java.util.Calendar;
import java.util.Collection;
import java.util.LinkedList;

import jp.android_group.attender.android.util.TextUtils;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

/**
 * イベントデータのモデル
 * 
 * @author Keiji Ariyama <keiji_ariyama@c-lis.co.jp>
 * 
 */
public class Event implements Serializable {
	private static final String LOG_TAG = "Event";
	private static final boolean DEBUG_FLG = true;

	/**
	 * 
	 */
	private static final long serialVersionUID = 7546901551094755375L;

	private int id = -1;
	private int eventCode = -1;
	private int serverId = -1;
	private String serverLabel = null;
	private String name = null;
	private long lastRetrieveDate = -1;

	/**
	 * 
	 * @return
	 */
	public String getLastRetrieveDateStr() {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(this.lastRetrieveDate);
		return TextUtils.cal2DateStr(cal);
	}

	private static final String EVENT_TABLE = "m_event";
	private static final String SERVER_ENTRY_TABLE = "m_server_entry";
	private static final String[] projection = new String[] {
			EVENT_TABLE + ".id" + " AS event_id",
			EVENT_TABLE + ".event_code" + " AS event_code",
			EVENT_TABLE + ".server_id" + " AS server_id",
			SERVER_ENTRY_TABLE + ".label" + " AS server_entry_label",
			EVENT_TABLE + ".name" + " AS event_name",
			EVENT_TABLE + ".last_retrieve_date"
					+ " AS event_last_retrieve_date" };

	/**
	 * イベントテーブルを作成
	 * 
	 * @param db
	 */
	public static void createTable(SQLiteDatabase db) {
		StringBuilder sql = new StringBuilder();
		sql.append("CREATE TABLE " + EVENT_TABLE);
		sql.append(" (");
		sql.append("id INTEGER PRIMARY KEY, ");
		sql.append("event_code INTEGER, ");
		sql.append("server_id INTEGER, ");
		sql.append("name TEXT, ");
		sql.append("last_retrieve_date TEXT ");
		sql.append(")");
		db.execSQL(sql.toString());
	}

	/**
	 * DBに保存
	 * 
	 * @param data
	 * @param db
	 */
	public static void save(Event data, SQLiteDatabase db) {
		ContentValues values = new ContentValues();
		values.put("event_code", data.getEventCode());
		values.put("server_id", data.getServerId());
		values.put("name", data.getName());
		if (data.getLastRetrieveDate() > 0) {
			values.put("last_retrieve_date", data.getLastRetrieveDate());
		}

		boolean existFlg = false;
		Collection<Event> list = load(data.getServerId(), data.getEventCode(),
				db);
		if (list.size() > 0)
			existFlg = true;

		if (existFlg == false) {
			db.insert(EVENT_TABLE, null, values);
		} else {
			db.update(EVENT_TABLE, values, "server_id = ? AND event_code = ?",
					new String[] { String.valueOf(data.getServerId()),
							String.valueOf(data.getEventCode()) });
			if (DEBUG_FLG)
				Log.v(LOG_TAG, "insert is failed. target data is updated");
		}
	}

	/**
	 * DBを読込み
	 * 
	 * @param db
	 * @return
	 */
	public static Collection<Event> load(SQLiteDatabase db) {
		LinkedList<Event> list = new LinkedList<Event>();
		Cursor cursor = db.query(EVENT_TABLE + "," + SERVER_ENTRY_TABLE,
				projection, EVENT_TABLE + ".server_id" + " = "
						+ SERVER_ENTRY_TABLE + ".id", new String[] {}, null,
				null, EVENT_TABLE + ".id desc");

		if (cursor.moveToFirst()) {
			do {
				list.add(fetchData(cursor));
			} while (cursor.moveToNext());
		}

		cursor.close();

		return list;
	}

	/**
	 * ＤＢを読込み
	 * 
	 * @param db
	 * @return
	 */
	public static Collection<Event> load(int serverId, int eventCode,
			SQLiteDatabase db) {
		LinkedList<Event> list = new LinkedList<Event>();
		Cursor cursor = db.query(EVENT_TABLE + "," + SERVER_ENTRY_TABLE,
				projection, "server_id = ? AND event_code = ?" + " AND "
						+ EVENT_TABLE + ".server_id" + " = "
						+ SERVER_ENTRY_TABLE + ".id", new String[] {
						String.valueOf(serverId), String.valueOf(eventCode) },
				null, null, EVENT_TABLE + ".id desc");

		if (cursor.moveToFirst()) {
			do {
				list.add(fetchData(cursor));
			} while (cursor.moveToNext());
		}

		cursor.close();

		return list;
	}

	/**
	 * データのフェッチ
	 * 
	 * @param cursor
	 * @return
	 */
	private static Event fetchData(Cursor cursor) {

		Event data = new Event();
		data.setId(cursor.getInt(cursor.getColumnIndex("event_id")));
		data.setEventCode(cursor.getInt(cursor.getColumnIndex("event_code")));
		data.setServerId(cursor.getInt(cursor.getColumnIndex("server_id")));
		data.setServerLabel(cursor.getString(cursor
				.getColumnIndex("server_entry_label")));
		data.setName(cursor.getString(cursor.getColumnIndex("event_name")));

		String lastRetrieveDate = cursor.getString(cursor
				.getColumnIndex("event_last_retrieve_date"));
		if (lastRetrieveDate != null)
			data.setLastRetrieveDate(Long.parseLong(lastRetrieveDate));

		return data;
	}

	/*
	 * setter and getter
	 */

	public int getId() {
		return id;
	}

	public void setId(int val) {
		id = val;
	}

	/**
	 * @param _eventCode
	 *            the _eventCode to set
	 */
	public void setEventCode(int _eventCode) {
		this.eventCode = _eventCode;
	}

	/**
	 * @return the _eventCode
	 */
	public int getEventCode() {
		return eventCode;
	}

	/**
	 * @param _serverId
	 *            the _serverId to set
	 */
	public void setServerId(int _serverId) {
		this.serverId = _serverId;
	}

	/**
	 * @return the _serverId
	 */
	public int getServerId() {
		return serverId;
	}

	/**
	 * @param serverLabel
	 *            the serverLabel to set
	 */
	public void setServerLabel(String serverLabel) {
		this.serverLabel = serverLabel;
	}

	/**
	 * @return the serverLabel
	 */
	public String getServerLabel() {
		return serverLabel;
	}

	public String getName() {
		return name;
	}

	public void setName(String val) {
		name = val;
	}

	/**
	 * @param lastRetrieveDate
	 *            the lastRetrieveDate to set
	 */
	public void setLastRetrieveDate(long lastRetrieveDate) {
		this.lastRetrieveDate = lastRetrieveDate;
	}

	/**
	 * @return the lastRetrieveDate
	 */
	public long getLastRetrieveDate() {
		return lastRetrieveDate;
	}

	/*
	 * setter and getter
	 */

}
